package by.msokoloff.javaweb2015.webapp.page.city;

import java.util.Iterator;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.metamodel.SingularAttribute;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.resource.ContextRelativeResource;
import org.apache.wicket.request.resource.IResource;

import by.msokoloff.javaweb2015.datamodel.City;
import by.msokoloff.javaweb2015.datamodel.City_;
import by.msokoloff.javaweb2015.datamodel.Country;
import by.msokoloff.javaweb2015.datamodel.Country_;
import by.msokoloff.javaweb2015.services.CityService;
import by.msokoloff.javaweb2015.services.CountryService;
import by.msokoloff.javaweb2015.webapp.page.EntityEditPage;
import by.msokoloff.javaweb2015.webapp.utils.renderer.CountryChoiceRenderer;

public class CityListPanel extends Panel {

	@Inject
	private CityService cityService;

	@Inject
	private CountryService countryService;

	public CityListPanel(String id) {
		super(id);

		List<Country> countries = countryService.getAll(Country_.name, true, 0, (int) (long) countryService.getCount());
		countries.add(0, new Country());
		
		CityDataProvider dp = new CityDataProvider();
		CityDataView dv = new CityDataView("list", dp, 25);
		PagingNavigator pn = new PagingNavigator("paging", dv);
		OrderByBorder<SingularAttribute<City, ?>> obb = new OrderByBorder<SingularAttribute<City, ?>>("sortByName", City_.name, dp);
		
		WebMarkupContainer tableBody = new WebMarkupContainer("wrapper-body");
		tableBody.add(dv);
		tableBody.add(pn);
		tableBody.add(obb);
		tableBody.setOutputMarkupId(true);
		add(tableBody);
		
		DropDownChoice<Country> cddc = new DropDownChoice<Country>("cddc", new CompoundPropertyModel<Country>(countries.get(0)), countries, CountryChoiceRenderer.INSTANCE);
		cddc.add(new AjaxFormComponentUpdatingBehavior("change") {
			
			@Override
			protected void onUpdate(AjaxRequestTarget target) {
				
				CityDataProvider dp = new CityDataProvider(cddc.getModelObject());

				tableBody.remove(pn);
				tableBody.remove(dv);
				tableBody.remove(obb);

				CityDataView dv = new CityDataView("list", dp, 25);
				tableBody.add(dv);

				PagingNavigator pn = new PagingNavigator("paging", dv);
				tableBody.add(pn);
				
				OrderByBorder<SingularAttribute<City, ?>> obb = new OrderByBorder<SingularAttribute<City, ?>>("sortByName", City_.name, dp);
				tableBody.add(obb);

				target.add(tableBody);
				
			}
		});

		add(cddc);
		

		add(new Link<Void>("create") {

			@Override
			public void onClick() {
				setResponsePage(new EntityEditPage(new City()));

			}

		});
	}

	private class CityDataProvider extends SortableDataProvider<City, SingularAttribute<City, ?>> {

		Country country = null;

		public CityDataProvider() {
			super();
			setSort(City_.name, SortOrder.ASCENDING);
		}

		public CityDataProvider(Country country) {
			this();
			if (country.getId() != null) {
				this.country = country;
			} else {
				this.country = null;
			}
		}

		@Override
		public Iterator<? extends City> iterator(long first, long count) {
			SingularAttribute<City, ?> sortParam = getSort().getProperty();
			SortOrder propertySortOrder = getSortState().getPropertySortOrder(sortParam);
			boolean ascending = SortOrder.ASCENDING.equals(propertySortOrder);
			if (country == null) {
				return cityService.getAll(sortParam, ascending, (int) first, (int) count).iterator();
			} else {
				return cityService.getAll(City_.country, country, sortParam, ascending, (int) first, (int) count).iterator();
			}
		}

		@Override
		public long size() {
			if (country == null) {
				return cityService.getCount();
			} else {
				return cityService.getCountByField(City_.country, country);
			}
		}

		@Override
		public IModel<City> model(City city) {
			return new CompoundPropertyModel<City>(city);
		}

	}

	private class CityDataView extends DataView<City> {

		protected CityDataView(String id, IDataProvider<City> dataProvider, long itemsPerPage) {
			super(id, dataProvider, itemsPerPage);
		}

		@Override
		protected void populateItem(Item<City> item) {

			IResource editIconResource = new ContextRelativeResource("img/editIcon.png");
			IResource deleteIconResource = new ContextRelativeResource("img/deleteIcon.png");

			City city = item.getModelObject();
			item.add(new Label("id"));
			item.add(new Label("name"));
			item.add(new Label("country", city.getCountry().getName()));

			Link<Void> editLink = new Link<Void>("edit") {

				@Override
				public void onClick() {
					setResponsePage(new EntityEditPage(city));

				}

			};

			editLink.add(new Image("editicon", editIconResource));
			item.add(editLink);

			Link<Void> deleteLink = new Link<Void>("delete") {

				@Override
				public void onClick() {
					// TODO Auto-generated method stub

				}

			};

			deleteLink.add(new Image("deleteicon", deleteIconResource));
			item.add(deleteLink);

		}

	}

}
